import "babel-polyfill";
import {nthElement, nthElementPartition} from "../../algorithm/array";

const compare_number = (x, y) => x - y;

export var mean = function() {
    return this.reduce((x, y) => x + y) / this.length;
};

export var median = function() {
    var n = this.length;
    var half = n >>> 1;
    if (n & 1) {
        return array::nthElement(half, compare_number);
    } else {
        let array = this.slice()::nthElementPartition(half, compare_number);
        let max = array[0];
        for (let i = half; --i > 0;) {
            if (array[i] > max) {
                max = array[i];
            }
        }
        return (max + array[half]) / 2;
    }
};

export var medianLow = function() {
    return this::nthElement((this.length - 1) >>> 1, compare_number);
};

export var medianHigh = function() {
    return this::nthElement(this.length >>> 1, compare_number);
};

export var variance = function() {
    var length = this.length;
    var sum = 0;
    var square_sum = 0;
    this.forEach(function(x) {
        sum += x;
        square_sum += x * x;
    });
    return square_sum / length - (sum / length) ** 2;
};

export var sampleVariance = function() {
    return this::variance() * (1 - 1 / this.length);
};

export var standardDeviation = function() {
    return Math.sqrt(this::variance());
};

export var sampleStandardDeviation = function() {
    return Math.sqrt(this::sampleVariance());
};
